home *** CD-ROM | disk | FTP | other *** search
/ Aminet 24 / Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso / Aminet / dev / c / cpost_1_4.lha / ctok.c < prev    next >
C/C++ Source or Header  |  1995-05-09  |  17KB  |  550 lines

  1. /*------------------------------------------------------------------
  2.  * ctok : C language tokenizer
  3.  *------------------------------------------------------------------
  4.  * 10-01-91 Patrick J. Mueller
  5.  *------------------------------------------------------------------*/
  6.  
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <ctype.h>
  11.  
  12. #include "ctok.h"
  13.  
  14. /*------------------------------------------------------------------
  15.  * is a character a valid character in a C identifier
  16.  *------------------------------------------------------------------*/
  17. #define isCsymbol(c) (isalnum(c) || ('_' == c))
  18.  
  19. /*------------------------------------------------------------------
  20.  * typedefs
  21.  *------------------------------------------------------------------*/
  22. typedef struct
  23.    {
  24.    int            eof;
  25.    char          *buffer;
  26.    long           bufferLen;
  27.    long           bufferInd;
  28.    long           fileOffs;
  29.    long           line;
  30.    int            unGetChar;
  31.    int            unGetReady;
  32.    long           tokOffs;
  33.    long           tokLen;
  34.    CTokRead       readFunc;
  35.    void          *readInfo;
  36.    char           ident[MAX_IDENT_LEN+1];
  37.    } CTokInfo;
  38.  
  39. /*-/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-*/
  40. /*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
  41.  
  42. /*------------------------------------------------------------------
  43.  * get next char from file
  44.  *------------------------------------------------------------------*/
  45. void GetNextChar(
  46.    int         *c,
  47.    CTokInfo    *cti
  48.    )
  49.    {
  50.    cti->fileOffs++;
  51.  
  52.    /*---------------------------------------------------------------
  53.     * check for end of file
  54.     *---------------------------------------------------------------*/
  55.    if (cti->eof)
  56.       {
  57.       *c = EOF;
  58.       return;
  59.       }
  60.  
  61.    /*---------------------------------------------------------------
  62.     * check for a char in the unget holder
  63.     *---------------------------------------------------------------*/
  64.    if (cti->unGetReady)
  65.       {
  66.       cti->unGetReady = 0;
  67.       *c = cti->unGetChar;
  68.  
  69.       if ('\n' == *c)
  70.          cti->line++;
  71.       return;
  72.       }
  73.  
  74.    /*---------------------------------------------------------------
  75.     * see if we need to read another buffer
  76.     *---------------------------------------------------------------*/
  77.    if (cti->bufferInd == cti->bufferLen)
  78.       {
  79.       cti->bufferLen = cti->readFunc(cti->readInfo,&(cti->buffer));
  80.       cti->bufferInd = 0L;
  81.  
  82.       if (0L == cti->bufferLen)
  83.          {
  84.          *c = EOF;
  85.          cti->eof = 1;
  86.          return;
  87.          }
  88.       }
  89.  
  90.    /*---------------------------------------------------------------
  91.     * read character from buffer
  92.     *---------------------------------------------------------------*/
  93.    *c = cti->buffer[cti->bufferInd++];
  94.  
  95.    if ('\n' == *c)
  96.       cti->line++;
  97.  
  98.    return;
  99.    }
  100.  
  101. /*------------------------------------------------------------------
  102.  * put back last char from file
  103.  *------------------------------------------------------------------*/
  104. void UnGetNextChar(
  105.    int          c,
  106.    CTokInfo    *cti
  107.    )
  108.    {
  109.    cti->fileOffs--;
  110.  
  111.    cti->unGetChar  = c;
  112.    cti->unGetReady = 1;
  113.  
  114.    if ('\n' == c)
  115.       cti->line--;
  116.    }
  117.  
  118. /*-/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-*/
  119. /*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
  120.  
  121. /*------------------------------------------------------------------
  122.  * read a C character constant or string
  123.  *------------------------------------------------------------------*/
  124. static void ReadString(
  125.    CTokInfo    *cti,
  126.    int          c
  127.    )
  128.    {
  129.    int stop;
  130.  
  131.    /*---------------------------------------------------------------
  132.     * the character passed in is ' or ", and it is the character that
  133.     * signifies the end of the string
  134.     *---------------------------------------------------------------*/
  135.    stop = c;
  136.  
  137.    /*---------------------------------------------------------------
  138.     * keep going until we hit our stop character
  139.     *---------------------------------------------------------------*/
  140.    GetNextChar(&c,cti);
  141.    while (stop != c)
  142.       {
  143.       /*------------------------------------------------------------
  144.        * for a \, inhale next character
  145.        *------------------------------------------------------------*/
  146.       if ('\\' == c)
  147.          GetNextChar(&c,cti);
  148.  
  149.       /*------------------------------------------------------------
  150.        * for EOF, break
  151.        *------------------------------------------------------------*/
  152.       if (EOF == c)
  153.          break;
  154.  
  155.       GetNextChar(&c,cti);
  156.       }
  157.  
  158.    return;
  159.    }
  160.  
  161. /*------------------------------------------------------------------
  162.  * read a C comment
  163.  *------------------------------------------------------------------*/
  164. static void ReadComment(
  165.    CTokInfo    *cti
  166.    )
  167.    {
  168.    int c;
  169.  
  170.    /*---------------------------------------------------------------
  171.     * loop until end of file (or return in middle)
  172.     *---------------------------------------------------------------*/
  173.    GetNextChar(&c,cti);
  174.    while (EOF != c)
  175.       {
  176.  
  177.       /*------------------------------------------------------------
  178.        * if not *, just get next character
  179.        *------------------------------------------------------------*/
  180.       if ('*' != c)
  181.          GetNextChar(&c,cti);
  182.  
  183.       /*------------------------------------------------------------
  184.        * got a * - see if next is /
  185.        *------------------------------------------------------------*/
  186.       else
  187.          {
  188.          /*---------------------------------------------------------
  189.           * if next is /, return
  190.           *---------------------------------------------------------*/
  191.          GetNextChar(&c,cti);
  192.          if ('/'  == c)
  193.             return;
  194.          }
  195.  
  196.       }
  197.  
  198.    return;
  199.    }
  200.  
  201. /*------------------------------------------------------------------
  202.  * read a C++ style comment
  203.  *------------------------------------------------------------------*/
  204. static void ReadCppComment(
  205.    CTokInfo    *cti
  206.    )
  207.    {
  208.    int c;
  209.  
  210.    /*---------------------------------------------------------------
  211.     * loop until end of line or end of file
  212.     *---------------------------------------------------------------*/
  213.    GetNextChar(&c,cti);
  214.  
  215.    while ((EOF != c) && ('\n' != c))
  216.       GetNextChar(&c,cti);
  217.  
  218.    UnGetNextChar(c,cti);
  219.    return;
  220.    }
  221.  
  222. /*------------------------------------------------------------------
  223.  * read an identifier
  224.  *------------------------------------------------------------------*/
  225. static void ReadIdent(
  226.    CTokInfo    *cti,
  227.    int          c
  228.    )
  229.    {
  230.    int identLen;
  231.  
  232.    /*---------------------------------------------------------------
  233.     * initialize length and stick first char in
  234.     *---------------------------------------------------------------*/
  235.    identLen = 0;
  236.    cti->ident[identLen++] = (char) c;
  237.  
  238.    /*---------------------------------------------------------------
  239.     * while still a valid symbol character ...
  240.     *---------------------------------------------------------------*/
  241.    GetNextChar(&c,cti);
  242.    while (isCsymbol(c))
  243.       {
  244.       /*------------------------------------------------------------
  245.        * make sure we got enough room, then stick it in
  246.        *------------------------------------------------------------*/
  247.       if (identLen < MAX_IDENT_LEN)
  248.          cti->ident[identLen++] = (char) c;
  249.  
  250.       GetNextChar(&c,cti);
  251.       }
  252.  
  253.    /*---------------------------------------------------------------
  254.     * finish up identifier, put last character back
  255.     *---------------------------------------------------------------*/
  256.    cti->ident[identLen] = '\0';
  257.    UnGetNextChar(c,cti);
  258.    }
  259.  
  260. /*------------------------------------------------------------------
  261.  * read a number
  262.  *------------------------------------------------------------------*/
  263. static void ReadNumber(
  264.    CTokInfo    *cti,
  265.    int          c
  266.    )
  267.    {
  268.  
  269.    /*---------------------------------------------------------------
  270.     * while still a valid number character ...
  271.     *---------------------------------------------------------------*/
  272.    GetNextChar(&c,cti);
  273.    while (isalnum(c))
  274.       GetNextChar(&c,cti);
  275.  
  276.    /*------------------------------------